package com.buddy.sds.auth.filter;

import com.buddy.sds.auth.entity.SystemPermission;
import com.buddy.sds.auth.entity.SystemRole;
import com.buddy.sds.auth.entity.SystemUser;
import com.buddy.sds.auth.service.ISystemPermissionService;
import com.buddy.sds.common.properties.RunMode;
import com.buddy.sds.common.properties.SDSProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Slf4j
public abstract class BaseAuthenticatingFilter extends AuthenticatingFilter {


    @Autowired
    private ISystemPermissionService permissionService;

    @Autowired
    private SDSProperties sdsProperties;


    boolean checkUrlPermission(RunMode runMode,String reqUrl){
        //认证完成  开始进行授权检查


        AntPathMatcher pathMatcher = new AntPathMatcher();

        if (runMode == RunMode.DEV) {
            //当前运行模式是开发模式 直接允许访问所有接口,不过前提是必须身份认证通过
            return true;
        }


        SystemUser systemUser = (SystemUser) SecurityUtils.getSubject().getPrincipal();

        List<SystemRole> roles = systemUser.getRoles();

        for (SystemRole role : roles) {


            List<SystemPermission> permissions = role.getPermissions();

            for (SystemPermission permission : permissions) {


                if (pathMatcher.match(permission.getPermissionUrl(), reqUrl)) {

                   // log.debug("路径匹配成功{},{}", permission.getPermissionUrl(), reqUrl);

                    return true;
                }

            }
        }

        return false;
    }

    protected abstract boolean hasAuthorizationHeader(ServletRequest request);



    /**
     * 进行登录认证
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {


        boolean allow = false;


        HttpServletRequest servletRequest = (HttpServletRequest) request;


        //根据url进行匹配权限

        String reqUrl = servletRequest.getRequestURI();

        log.debug("请求Url:{}", reqUrl);

        AntPathMatcher pathMatcher = new AntPathMatcher();


        List<String> ignoreList = permissionService.getIgnoreUrlList();

        for (String url : ignoreList) {

            if (pathMatcher.match(url, reqUrl)) {

                log.debug("路径{} 无需授权，放行", url);

                return true;
            }

        }


        //Subject与线程绑定  认证完成后subject中保存了角色权限信息
        Subject subject = SecurityUtils.getSubject();


            if (subject.isAuthenticated()) {

                return true;

            }

            if (hasAuthorizationHeader(request)) {

                try {

                    allow = executeLogin(request, response);

                } catch (Exception e) {

                    log.error(e.getMessage());

                    return false;
                }
            }



        if (allow) {

            allow = this.checkUrlPermission(sdsProperties.getRunMode(),reqUrl);
        }


        return allow | isPermissive(mappedValue);
    }


}
